# -*- encoding: utf-8 -*-

"""
@File:      tc_libtdb_libtdb_func_005.py.py
@Time:      2024/04/18 14:33:20
@Author:    chenchunhu
@Version:   1.0
@Contact:   wb-cch358909@alibaba-inc.com
@License:   Mulan PSL v2
@Modify:    chenchunhu
"""

from common.basetest import LocalTest

class Test(LocalTest):
    """
    See tc_libtdb_libtdb_func_005.py.yaml for details

    :avocado: tags=P2,noarch,local,fix
    """

    PARAM_DIC = {"pkg_name": "libtdb libtdb-devel gcc"}
    def setUp(self):
        super().setUp(self.PARAM_DIC)
        cmdline = '''cat >ltdb_test5.c<<"EOF"
#include <stdio.h>
#include <stdlib.h>
#include <tdb.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>

#define NUM_PROCESSES 5 //正在启动的子进程数量

int main() {
    int i;
    pid_t pid;
    TDB_CONTEXT *tdb;

    tdb = tdb_open("ltdb_test5.tdb", 0, TDB_DEFAULT | TDB_CLEAR_IF_FIRST, O_CREAT | O_RDWR, 0644);
    if (tdb == NULL) {
        fprintf(stderr, "打开或创建数据库失败\\n");
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < NUM_PROCESSES; i++) {
        pid = fork();
        if (pid == 0) { // 这是子进程
            // 子进程: 向数据库写入键值对
            char key[256];
            char value[256];
            // 以子进程的标号构造键和值
            sprintf(key, "key%d", i);
            sprintf(value, "value%d", i);
            TDB_DATA tdb_key, tdb_value;
            tdb_key.dptr = (unsigned char *)key;
            tdb_key.dsize = sizeof(key);
            tdb_value.dptr = (unsigned char *)value;
            tdb_value.dsize = sizeof(value);

            if (tdb_store(tdb, tdb_key, tdb_value, TDB_INSERT) != 0) {
                fprintf(stderr, "子进程 %d: 键值对写入失败\\n", i);
                tdb_close(tdb);
                exit(EXIT_FAILURE);
            }
            printf("子进程 %d: 已写入键值对 %s:%s\\n", i, key, value);

            // 成功后关闭数据库并退出子进程
            tdb_close(tdb);
            exit(EXIT_SUCCESS);
        } else if (pid > 0) {
            // Parent process: 继续创建下一个子进程
        } else {
            fprintf(stderr, "无法创建子进程\\n");
            tdb_close(tdb);
            exit(EXIT_FAILURE);
        }
    }

    // 等待所有子进程结束
    while ((pid = waitpid(-1, NULL, 0))) {
        if (errno == ECHILD) {
            break;
        }
    }

    // 关闭数据库
    tdb_close(tdb);

    printf("所有子进程均已完成写入。\\n");
    
    return 0;
}
EOF'''
        self.cmd(cmdline)


    def test(self):
        self.cmd("gcc -o ltdb_test5 ltdb_test5.c -ltdb")
        code, ltdb_result = self.cmd("./ltdb_test5")
        self.assertIn('所有子进程均已完成写入', ltdb_result)

    def tearDown(self):
        super().tearDown(self.PARAM_DIC)
        self.cmd("rm -rf ltdb_test5.c ltdb_test5 ltdb_test5.tdb")
